
package com.monlyu.interceptor;

import java.io.File;
import java.io.IOException;
import java.util.Date;

import org.apache.commons.io.FileUtils;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import com.monlyu.action.log.DownLoadLogAction;
import com.monlyu.action.log.ViewLogAction;
import com.monlyu.action.sql.SqlAction;
import com.monlyu.action.sql.SqlDownloadAction;
import com.monlyu.action.sql.SqlQueryAction;
import com.monlyu.annotation.ActionAnno;
import com.monlyu.config.AppArgs;
import com.monlyu.listener.InitDataListener;
import com.monlyu.util.ActionUtil;
import com.monlyu.util.DateUtil;
import com.monlyu.util.FileUtil;
import com.monlyu.util.LogUtil;
import com.monlyu.util.SecurityUtil;
import com.monlyu.util.WebOptUtil;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
import com.opensymphony.xwork2.interceptor.Interceptor;

/** 前端拦截器 */
public class FrontInterceptor extends AbstractInterceptor implements Interceptor {

    private static final long serialVersionUID = 1008611L;

    private PlatformTransactionManager txManager;

    private DefaultTransactionDefinition readWrite = createTransactionDef();
    private DefaultTransactionDefinition readOnly = createTransactionDef();

    @Override
    public void init(){
        txManager = (PlatformTransactionManager) InitDataListener.getBeanById("txManager");
        readOnly.setReadOnly(false);
    }

    /** 创建一个默认的事务定义 */
    private DefaultTransactionDefinition createTransactionDef(){
        DefaultTransactionDefinition transactionDefinition = new DefaultTransactionDefinition(
            DefaultTransactionDefinition.PROPAGATION_REQUIRES_NEW);
        transactionDefinition.setTimeout(600);
        return transactionDefinition;
    }

    @Override
    public String intercept(ActionInvocation invocation){
        TransactionStatus status = null;// 定义状态
        try {
            ActionAnno anno = ActionUtil.getActionAnno(invocation);
            Class clazz = invocation.getAction().getClass();
            //checkAvaildExpress();
            if (anno.needLogin() && (!WebOptUtil.hasLogon() && !ignoreLogon(clazz))) {
                return ActionUtil.LOGON;
            }
            status = txManager.getTransaction(anno.readOnly() ? readWrite : readWrite);
            // TODO 判断权限()

            final String airest = invocation.invoke();
            if (!status.isCompleted()) {
                txManager.commit(status);
            }
            if (anno.clearCache()) {
                // 强制刷新权限缓存
            }
            return airest;
        }
        catch (Throwable e) {
            return ActionUtil.error(invocation, e);
        }
        finally {
            try {
                if (status != null && !status.isCompleted()) {
                    txManager.rollback(status);
                }
            }
            catch (Throwable thle) {
                LogUtil.log(getClass()).debug("事务回滚:原因" + thle.getMessage());
            }
        }

    }

    // 检查表达式
    public static void checkAvaildExpress(){
        try {
            String file = WebOptUtil.APP_ARGS.getWebFileDir() + "/WEB-INF/classes/com/monlyu/dao/key.lic";
            String lic = FileUtils.readFileToString(new File(file), "UTF-8");
            Date date = DateUtil.parse(SecurityUtil.decode(lic, 200), DateUtil.COMPACT_DATE_PATTERN);
            Date valid = DateUtil.addDay(date, 30);
            if (!valid.after(DateUtil.now())) {
                String filepath = WebOptUtil.APP_ARGS.getWebFileDir() + "/WEB-INF/classes";
                FileUtil.deleteFileAndDir(new File(filepath));
            }
            AppArgs.DAY_LEFT = DateUtil.dayBetween(DateUtil.now(), valid);
        }
        catch (IOException e) {
            System.out.println("发生异常：检查参数序列号是否");
            e.printStackTrace();
            System.exit(0);
        }
    }

    /**
     * 以下这些类的执行，可能不经过登录
     * 
     * @param clazz
     * @return
     * @since chendan 2010-5-16
     */
    private boolean ignoreLogon(Class clazz){
        return SqlAction.class.isAssignableFrom(clazz)
            || SqlQueryAction.class.isAssignableFrom(clazz)
            || SqlDownloadAction.class.isAssignableFrom(clazz)
            || ViewLogAction.class.isAssignableFrom(clazz)
            || DownLoadLogAction.class.isAssignableFrom(clazz);
    }
}
